package jj.connector;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.namespace.QName;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import jj.common.Constant;
import jj.vo.Flight;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.lf5.util.StreamUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.tidy.Configuration;
import org.w3c.tidy.Tidy;

import com.mongodb.io.StreamUtil;
import com.sun.org.apache.xerces.internal.util.HTTPInputSource;
import com.sun.xml.internal.ws.util.StringUtils;


/**
 * @목적 : 실제 Connection을 연결하여 List<Flight> 정보를 가져온다.
 * @접근방법1 : 일정한 Thread주기에 따라서, 자동으로 가져옴
 * @접근방법2 : 사용자가 강제 '새로고침' 할 경우
 * @접근방법3 : 첫 실행시, 로컬 서버가 죽을 경우 무조건 서버로 접속
 *
 */
public class AirConnector {
	XPathFactory factory = XPathFactory.newInstance();
	XPath x = factory.newXPath();
	
	final Logger log = Logger.getLogger(AirConnector.class);
	
	public List<Flight> getDocumentByParam(String depart, String date, String airport) throws MalformedURLException, IOException, XPathExpressionException{
		Map<String, String> paramObject = new HashMap<String, String>();
		paramObject.put("depArr", depart);
		paramObject.put("current_date", date);
		paramObject.put("airport", airport);
		
		StringBuilder url = new StringBuilder(Constant.BASE_INFO_URL);
		Object[] keys = paramObject.keySet().toArray();
		for(int i=0; i<keys.length; i++){
			url.append("&" + keys[i] + "="+paramObject.get(keys[i]));
		}
		
		if(log.isDebugEnabled()){
			log.debug("URL = " + url.toString() );
		}
		
		Tidy tidy = new Tidy();
		tidy.setInputEncoding(Constant.COMMON_ENCODING);
		tidy.setOutputEncoding(Constant.COMMON_ENCODING);
		Document document = tidy.parseDOM(new URL(url.toString()).openStream(), null);
		
		return parse(document, paramObject);
	}


	public List<Flight> parse(Document doc, Map<String, String> param) throws XPathExpressionException{
		boolean depart = param.get("depArr") == "A" ? true : false;
		String orgCity = param.get("airport");
		List<Flight> result = new ArrayList<Flight>();
		
		NodeList trs = (NodeList) findXpath(doc, "//table/tr/td/table/tr", XPathConstants.NODESET);

		for (int i=0, length=trs.getLength(); i < length; i++) {
			Node tr = trs.item(i);
			if ( tr.getChildNodes().getLength() < 2 ) continue; 			// layout을 위해 빈 tr이 존재한다.
			
			// 항공사명, 항공기번호, 출도착도시, 시각1,시각2,시각3
			String FlightName = (String)findXpath(tr, "td/a/text()", XPathConstants.STRING); 
			String FlightNum = (String)findXpath(tr, "td[3]", XPathConstants.STRING);
			String city = (String)findXpath(tr, "td[5]", XPathConstants.STRING);
			String time1 = (String)findXpath(tr, "td[7]", XPathConstants.STRING);
			String time2 = (String)findXpath(tr, "td[9]", XPathConstants.STRING);
			String time3 = (String)findXpath(tr, "td[11]", XPathConstants.STRING);
			String status = (String)findXpath(tr, "td[15]", XPathConstants.STRING);
			if(FlightName == "" || FlightNum == "") continue;
			
			Flight entry = new Flight();
			//TODO 각 변수를 설정
			
			if(depart){
				entry.setArrivalCity(orgCity);
				entry.setDepartCity(city);
			}else{
				entry.setArrivalCity(city);
				entry.setDepartCity(orgCity);
			}

			entry.setFilghtCorpName(FlightName);
			entry.setFlightNumber(FlightNum);
			entry.setFlightPrefixName(null);
			entry.setIsDomestic(null);
			entry.setPlanTime(time1);
			entry.setRealTime(time2);
			entry.setStatus(status);
			entry.setWillTime(time3);
			
			
			result.add(entry);
		}
		return result;
	}
	
	private Object findXpath (Object item, String expr, QName qname) throws XPathExpressionException {
		XPathExpression exp = x.compile(expr);
		return exp.evaluate(item, qname);
	}

}	
